// AC
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5;

int n, m;              // n: 点的数量，m 边的数量
set<int> nxt[N];       // 每个点的邻集
pair<int, int> edg[N]; // 存边的信息：起点->终点

struct UnionSet {
  int father[N], size[N];
  void init(int n) {
    for (int i = 1; i <= n; i++) {
      father[i] = i;
      size[i] = 1;
    }
  }

  int find(int x) {
    if (father[x] == x)
      return x;
    return father[x] = find(father[x]);
  }
  void unionSet(int u, int v) {
    int fu = find(u);
    int fv = find(v);
    if (fu == fv)
      return;
    if (size[fu] < size[fv]) // 目的是将“小”的树，挂靠在“大”的树下方
      swap(fu, fv);

    for (auto son : nxt[fv]) { // 将与fv相连的边，合并至fu
      nxt[son].erase(fv);      // 删除son -> fv的边
      m--;
      if (son != fu && !nxt[son].count(fu)) { // 增加son -> fu的边
        nxt[fu].insert(son);
        nxt[son].insert(fu);
        m++;
      }
    }
    size[fu] += size[fv];
    father[fv] = fu;
    nxt[fv].clear();
  }

  bool isSame(int x, int y) { return find(x) == find(y); }

} UF;

int main() {

  cin >> n >> m;

  UF.init(n);

  for (int i = 1; i <= m; i++) {
    int u, v;
    cin >> u >> v;
    edg[i] = {u, v};
    // edg.push_back({u, v});
    nxt[u].insert(v);
    nxt[v].insert(u);
  }
  int q;
  cin >> q;
  while (q--) {
    int id;
    cin >> id; // 读入边的编号
    int u, v;
    tie(u, v) = edg[id];    // 合并 u-v 这条边
    if (!UF.isSame(u, v)) { // u和v已经合并在一起了
      UF.unionSet(u, v);
    }
    cout << m << endl;
  }
  return 0;
}